-
Notifications
You must be signed in to change notification settings - Fork 1.8k
lint on binding-names that are too similar #727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Your problem is not because of macros but because of the for loop lowering, which does not change the expn_id so |
Also I’m not sure about that lint being Warn by default, it would lint |
sgtm |
http://manishearth.github.io/rust-internals-docs/syntax/codemap/struct.ExpnInfo.html suggests that |
|
BTW, why don’t you make that an |
made it an
|
@@ -90,12 +90,12 @@ impl Constant { | |||
impl PartialEq for Constant { | |||
fn eq(&self, other: &Constant) -> bool { | |||
match (self, other) { | |||
(&Constant::Str(ref ls, ref lsty), &Constant::Str(ref rs, ref rsty)) => ls == rs && lsty == rsty, | |||
(&Constant::Str(ref ls, ref l_sty), &Constant::Str(ref rs, ref r_sty)) => ls == rs && l_sty == r_sty, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don’t think there is any value added by all those _
, IMO it’s as easy to distinguish between l
and r
as between l_
and r_
. The lint seems more annoying than usefull :s
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
xD i thought so, too. But once I added the underscore, I found it much better. If it were a type, you wouldn't name it Rsty
but you'd name it RSty
. This is the snake-case variant of that.
Ok, so let’s see how annoying is your lint in the wild 😄:
src/compile.rs:629:31: 629:36 error: binding's name is too similar to existing binding
src/compile.rs:629 MaybeInst::Split2(goto2) => {
^~~~~
src/lib.rs:14:9: 14:22 note: lint level defined here
src/lib.rs:14 #![deny(similar_names)]
^~~~~~~~~~~~~
src/compile.rs:626:31: 626:36 note: existing binding defined here
src/compile.rs:626 MaybeInst::Split1(goto1) => {
^~~~~
src/compile.rs:629:31: 629:36 help: separate the discriminating character by an underscore like: `goto_2`
src/compile.rs:629 MaybeInst::Split2(goto2) => {
^~~~~
src/compile.rs:629:31: 629:36 help: for further information visit https://github.com/Manishearth/rust-clippy/wiki#similar_names
src/lib.rs:342:35: 342:41 error: binding's name is too similar to existing binding
src/lib.rs:342 Literal { chars: chars2, casei: casei2 }) => {
^~~~~~
src/lib.rs:4:9: 4:22 note: lint level defined here
src/lib.rs:4 #![deny(similar_names)]
^~~~~~~~~~~~~
src/lib.rs:341:44: 341:50 note: existing binding defined here
src/lib.rs:341 (Some(Literal { chars: mut chars1, casei: casei1 }),
^~~~~~
src/lib.rs:342:35: 342:41 help: separate the discriminating character by an underscore like: `chars_2`
src/lib.rs:342 Literal { chars: chars2, casei: casei2 }) => {
^~~~~~
src/lib.rs:342:35: 342:41 help: for further information visit https://github.com/Manishearth/rust-clippy/wiki#similar_names
src/lib.rs:342:50: 342:56 error: binding's name is too similar to existing binding
src/lib.rs:342 Literal { chars: chars2, casei: casei2 }) => {
^~~~~~
src/lib.rs:4:9: 4:22 note: lint level defined here
src/lib.rs:4 #![deny(similar_names)]
^~~~~~~~~~~~~
src/lib.rs:341:59: 341:65 note: existing binding defined here
src/lib.rs:341 (Some(Literal { chars: mut chars1, casei: casei1 }),
^~~~~~
src/lib.rs:342:50: 342:56 help: separate the discriminating character by an underscore like: `casei_2`
src/lib.rs:342 Literal { chars: chars2, casei: casei2 }) => {
^~~~~~
src/lib.rs:342:50: 342:56 help: for further information visit https://github.com/Manishearth/rust-clippy/wiki#similar_names
At least it does not seem to lint too often as I feared. |
numbering binding names isn't a great way to differentiate names. Separating out the discriminating character with an underscore is much clearer imo. Especially in cases like |
but I think the warnings you are getting are a bug in my code anyway since they seem to be in different arms. I thought I was just checking whether a single scope ever had collisions. |
whoops. The issue was that scoping didn't work if it was inside the initialization expression of a let binding (like in the regex crate). That is fixed now. Doesn't change anything in the |
rebased |
ping? |
r? @mcarton |
Overall this is good, but I'd like @mcarton to sign off on it since he was the one reviewing. I wonder how efficient this is, since we're running levenshtein across every combination of two names in a scope. Can someone run a before/after |
@Manishearth on Cargo: Without Clippy:
time: 0.019; rss: 96MB early lint checks
time: 0.020; rss: 101MB early lint checks
time: 0.020; rss: 100MB early lint checks
time: 0.019; rss: 102MB early lint checks
time: 0.019; rss: 101MB early lint checks
time: 0.020; rss: 102MB early lint checks
time: 0.019; rss: 101MB early lint checks
With Manishearth:master:
time: 0.047; rss: 100MB early lint checks
time: 0.046; rss: 98MB early lint checks
time: 0.045; rss: 98MB early lint checks
time: 0.050; rss: 98MB early lint checks
time: 0.045; rss: 98MB early lint checks
time: 0.047; rss: 98MB early lint checks
time: 0.048; rss: 98MB early lint checks
time: 0.046; rss: 98MB early lint checks
time: 0.046; rss: 98MB early lint checks
time: 0.048; rss: 101MB early lint checks
With oli-obk:similar_names:
time: 0.154; rss: 100MB early lint checks
time: 0.162; rss: 102MB early lint checks
time: 0.157; rss: 103MB early lint checks
time: 0.152; rss: 102MB early lint checks
time: 0.155; rss: 98MB early lint checks
time: 0.158; rss: 98MB early lint checks
time: 0.158; rss: 98MB early lint checks
time: 0.160; rss: 98MB early lint checks
time: 0.157; rss: 98MB early lint checks
time: 0.163; rss: 98MB early lint checks The impact seems important. |
span, | ||
&format!("{}th binding whose name is just one char", | ||
self.0.single_char_names.len())); | ||
return; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The if foo { return; } bar(); return;
sequence is a little weird here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yea, that should be if foo { a } else { b } return;
iirc we have a lint that detects similar cases, I'll see if I can improve it.
Oh, that's a significant impact :/ There probably are specialized datastructures for handling this but that might lead to a lot of churn. What if we avoided levenshtein and instead did a simple similarity iteration? |
Actually, we don't need to calculate the levenshtein, we only need to find out if the distance is 1. Calculating the levenshtein is O(n^2), but determining if it's a given distance is O(n). Though for small n this may not matter much. shrug |
for reference, the timings on my machine
Note that with release builds there's no(t much) difference between my two versions. |
@@ -200,6 +201,9 @@ pub fn plugin_registrar(reg: &mut Registry) { | |||
reg.register_late_lint_pass(box types::CharLitAsU8); | |||
reg.register_late_lint_pass(box print::PrintLint); | |||
reg.register_late_lint_pass(box vec::UselessVec); | |||
reg.register_early_lint_pass(box non_expressive_names::NonExpressiveNames { | |||
max_single_char_names: 5, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that #698 has been merged, this can be configured. Just sayin' 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
addressed comments |
done |
rebased |
rebased |
//~| NOTE: lint level defined here | ||
//~| NOTE: lint level defined here | ||
//~| NOTE: lint level defined here | ||
//~| NOTE: lint level defined here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That’s weird, we never had to include that before. Must be because of the last upgrade of compiletest, but why is it needed only here?
I’m ok with that, @Manishearth? |
lint on binding-names that are too similar
This doesn't work, because out of some reason
in_macro
does not trigger for the for-loops infor_loop_over_option_and_result
incompile-fail/for_loops.rs
. Myvisit_name
code might be wrong, because I'm not sure what happens when ahir::Ident
is visited (are both the hygienic and non-hygienic name visited?), but even then should the span +in_macro
prevent this.Help? 🆘
cc #644